Fix stale SelectableStatic mouse events in TUI#461
Open
HamsteRider-m wants to merge 1 commit into
Open
Conversation
11 tasks
lsdefine
pushed a commit
that referenced
this pull request
May 28, 2026
v2 Ctrl+S freeze: defer reset() + cleanup via call_after_refresh so the keystroke handler returns immediately even when streaming has the reactive queue saturated. Added _skip_change_next flag to short-circuit on_input_area_changed during the deferred clear. v3 terminal title: route _set_term_title via os.write(1,...) — sys.stdout gets redirected to sb_agent.log during PTK app run, so OSC 0 escapes were silently ending up in the log file. Default _session_name = 'session' for v2 parity, and repaint title on running→idle transition. v3 input row bg fill: _tile() now pads explicit bg-active spaces to width — PTK's cell renderer doesn't honour \x1b[K (erase-to-EOL), so the user bubble's charcoal band used to stop at text length. v3 /emoji picker: arrow-key menu (mirrors /llm). Pet styles cleaned to bear (default) + cat + dot + unicode. Bear calm tier restored to ʕ•ᴥ•ʔ. • used for the calm tier, o for focused — matches user-requested mood progression. Pet frame rate decoupled from spinner via self._spin // 5. v3 ask_user "coderun freeze" fix: _tool_status no longer marks an in-flight ask_user chip as ✓ ok when the stream contains the "Waiting for your answer ..." marker. Bumped DoneEvent grace from 2 s to 10 s when the marker is in the stream so a slow ask_user_queue.put doesn't cause the picker to fall through to _finalize. v3 /scheduler picker: added pre_checked kwarg to _show_menu so the running set lands atomically. slash_cmds._match_service relaxed to path-only matching so directly-launched (`python reflect/foo.py`) reflect tasks are detected. Running rows highlighted in functional green. Confirm card accepts ← as cancel (parity with Esc) — same on v2 ChoiceList. v3 keybindings: Esc Esc (within 800 ms) → /rewind (handled in _handle_key so PTK's Esc interception path actually fires). v3 pending input queue: agent.task_dir wired so ga.turn_end_callback can consume `<task_dir>/_intervene`. New AgentBridge.inject_intervene appends to the file (atomic vs read-modify-write), and _drain_pending routes the combined message either through that hook (mid-turn) or via put_task (idle). Cooldown 5 s, resets per new pending. ↑ recalls the last queued message, Esc clears the queue. v2 has equivalent shape: AgentSession.pending + per-session agent.task_dir + _inject_intervene + _poll_pending timer. ! shell magic: prefix `!` enters shell mode — pink border, prompt mark swaps `❯` → `!`, body strips the leading `!` so the glyph appears once. Enter runs the rest as `subprocess.run(shell=True, timeout=30)`, echoes `! cmd` + `└ output` into scrollback, and appends to LLM history (via _intervene when agent is running, direct backend.history append when idle — sidesteps the iterator race). /resume: forwarded as a literal to the agent so GA's _handle_slash_cmd (agentmain.py:124) can expand it. Added to v3 _cmds() + v2 COMMANDS + slash_cmds.COMMANDS + i18n + /help + Tips. Turn marker regex fix: agent_loop.py:52 switches `**LLM Running (Turn N) ...**` to the short `**Turn N ...**` when task_dir is set. Extended all v3/v2 turn-marker regexes to match either form. Cherry-picked upstream fixes: - PR #466 (8ae3645): _collapse_choice early-return when the on_select callback (e.g. /rewind) detaches the anchor widget. - PR #461 (08f21e8): SelectableStatic.has_valid_selection_parent + app-level _is_stale_selectable_mouse_event filter that swallows mouse events on detached widgets.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SelectableStaticmessage widgets after refresh/remount cycles.MouseDownand stop staleMouseDown/MouseMovepropagation before Textual dispatch asserts on a missing parent.Verification
python3 -m py_compile frontends/tuiapp_v2.pypython3 -m unittest discover -s tests -vpython3 -m pytest tests/test_tui_stale_selectable.py -vVERDICT: PASSCloses #460